package cn.com.cym.gamezao.web;

import cn.com.cym.gamezao.annotation.AccessLimit;
import cn.com.cym.gamezao.annotation.CommonApi;
import cn.com.cym.gamezao.base.ResultResponse;
import cn.com.cym.gamezao.dto.UserDto;
import cn.com.cym.gamezao.entity.SendRes;
import cn.com.cym.gamezao.entity.Sms;
import cn.com.cym.gamezao.enums.ValidType;
import cn.com.cym.gamezao.exception.BaseException;
import cn.com.cym.gamezao.service.SmsService;
import cn.com.cym.gamezao.service.authorize.UserService;
import cn.com.cym.gamezao.util.*;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
import java.util.concurrent.TimeUnit;

@Api(tags = "x-获取私钥")
@RestController
@RequestMapping(value = "key")
@CommonApi
public class ApiController {


    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private HttpServletRequest request;

    final EntityManager entityManager;
    final UserService userService;

    final SmsService smsService;

    public ApiController(UserService userService,SmsService smsService,EntityManager entityManager){
        this.userService=userService;
        this.smsService=smsService;
        this.entityManager = entityManager;
    }

    /**
     * 获取私钥 按登录患者
     * @param userDto userDto
     * @return r
     */
    @ApiImplicitParam(name = "userDto", value = "userDto", required = true,dataType = "UserDto")
    @ApiOperation(value = "获取私钥")
    @ApiOperationSupport(order = 1, author = "mr.chen")
    @PostMapping("/privateKey")
    //TODO
    public ResponseEntity<?> postPrivateKey(@RequestBody UserDto userDto){
        var login = this.userService.login(userDto);
        ResultResponse resultResponse=new ResultResponse(RSAUtils.PUBLIC_KEY, HttpStatus.OK.value());
        return ResponseEntity.ok(resultResponse);
    }


    /**
     * 获取登录界面的验证码
     * @return 验证码
     */
    @ApiImplicitParam(name = "type", value = "type", paramType="path",required = true,dataType = "ValidType")
    @ApiOperation(value = "获取图片验证码")
    @ApiOperationSupport(order = 1, author = "mr.chen")
    @GetMapping("/loginValidCode/{type}")
    @AccessLimit(limitCount = 5)
    public ResponseEntity<?> getValidCode(@PathVariable ValidType type){
        ImageUtils.Validate randomCode = ImageUtils.getRandomCode();
        RedisTemplate<String, Object> redisTemplate = this.redisTemplate;
        String customIp = CommonUtils.customIp(request);
        redisTemplate.opsForValue().set(customIp+type.getSign(),randomCode.getValue());
        //5分钟失效
        //System.out.println(customIp+type.getSign());
        redisTemplate.expire(customIp+type.getSign(), ConstParams.VALID_CODE_EXPIRE, TimeUnit.SECONDS);
        return ResponseEntity.ok(new ResultResponse(randomCode.getBase64Str(),"",HttpStatus.OK.value()));
    }

    /**
     * 测试redis
     * @return r
     */
    @GetMapping("")
    public ResponseEntity<?> getPrivateKey(){
        RedisTemplate<String, Object> redisTemplate = this.redisTemplate;
        redisTemplate.opsForValue().set("niao","2323");
        redisTemplate.expire("niao",10L, TimeUnit.SECONDS);
        ResultResponse resultResponse=new ResultResponse("",HttpStatus.OK.value());
        return ResponseEntity.ok(resultResponse);
    }

    @GetMapping("sendSms")
    @ApiOperation(value = "发送短信")
    @ApiOperationSupport(order = 1, author = "mr.chen")
    @Deprecated
    public ResponseEntity<?> sendSms() throws IOException {
        SMSUtils s=new SMSUtils();
       /* s.setApId("pxtest");
        s.setEcName("厦门大学附属翔安医院");
        s.setUrl("https://112.35.10.201:28888/sms/submit");
        s.setSecretKey("Xayy@2021");
        s.setSign("wEa6sq9H3");*/
        Sms sms=new Sms();
        sms.setApId("pxtest");
        sms.setEcName("厦门大学附属翔安医院");
        sms.setUrl("https://112.35.10.201:28888/sms/submit");
        sms.setSecretKey("Xayy@2021");
        sms.setSign("wEa6sq9H3");

        SendRes sendRes = s.sendMsg(entityManager,sms, "", "{" +
                "\"18596814815\":\"你好\",\"17605097466\":\"卢指导你好呀\"}",true);
        return ResponseEntity.ok(sendRes);
    }

    @GetMapping("/sendSmsCode/{telNo}")
    @AccessLimit(limitCount = 2)
    public ResponseEntity<?> sendSmsValidCode(@PathVariable @NonNull Long telNo) throws IOException {
        //判断是否存在验证码
        final Object validCode = redisTemplate.opsForValue().get("telNo" + telNo);

        final Long expire = redisTemplate.opsForValue().getOperations().getExpire("telNo" + telNo);

        //判断是否临近失效
        if(validCode!=null && expire> (LocalDateTime.now().getLong(ChronoField.MICRO_OF_SECOND)+60)*1000){
            throw new BaseException("",new ResultResponse("",502));
        }

        //生成验证码
        final String random = CommonUtils.random(6, 6, 0);
        //System.out.println(random);
        redisTemplate.opsForValue().set("telNo"+telNo,random);
        redisTemplate.expire("telNo"+telNo,55*6L, TimeUnit.SECONDS);

        SMSUtils.sendMsg(entityManager,this.smsService.getAll().get(0),telNo+"","疫苗登记验证："+random+"(有效期5分钟),如非本人操作，请忽略此信息",true);

        return ResponseEntity.ok(random);
    }
}
